Skip to content

feat(solana-indexer) PR 9: cover the ingester to decoder pipeline end to end - #4677

Open
squadgazzz wants to merge 5 commits into
solana-indexer/PR8-persistfrom
solana-indexer/PR9-pipeline-test
Open

feat(solana-indexer) PR 9: cover the ingester to decoder pipeline end to end#4677
squadgazzz wants to merge 5 commits into
solana-indexer/PR8-persistfrom
solana-indexer/PR9-pipeline-test

Conversation

@squadgazzz

@squadgazzz squadgazzz commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Description

Nothing exercised the ingester and the decoder as one pipeline, because the per-component tests stop at the channel boundary. This runs a proto SubscribeUpdate carrying a CreateOrder through the real ingester, channel and decoder, then asserts what arrived at the persistence seam.

Changes

  • Persistence records every write as a Call under #[cfg(test)]. The log is shared across clones, so a test hands one clone to a component and reads back what that component wrote.
  • One pipeline test drives stream::iter into Ingester, through the channel, into Decoder::run, and asserts the decoder persisted the OrderCreated event with watermark 41 for a slot-42 transaction. That also pins the slot - 1 watermark rule across the whole path.

How to test

New unit test.

Related issues

Stacked on #4676.

@squadgazzz squadgazzz changed the title solana-indexer: cover the ingester to decoder pipeline end to end feat(solana-indexer) PR 9: cover the ingester to decoder pipeline end to end Jul 28, 2026
@squadgazzz
squadgazzz marked this pull request as ready for review July 30, 2026 16:27
@squadgazzz
squadgazzz requested a review from a team as a code owner July 30, 2026 16:27
@squadgazzz
squadgazzz requested a review from tilacog July 30, 2026 16:27
@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Claude finished @squadgazzz's task in 4m 0s —— View job


PR Review — solana-indexer PR 9

  • Read changed files & diff
  • Review persistence.rs test harness
  • Review pipeline test
  • Post inline findings & summary

Verdict: Looks good. The test harness and the end-to-end pipeline test are clean, correct, and well-documented.

What I checked:

  • The Persistence #[cfg(test)] Call recording is sound — the Arc<Mutex<Vec<Call>>> is shared across clones, so handing the decoder a clone() and reading calls() on the original observes exactly what the decoder wrote.
  • The pipeline test genuinely spans the channel: stream::iterIngester::run → bounded channel → Decoder::run → persistence seam. Running the two stages sequentially is safe here (one buffered message, capacity 16) and pins the slot 42 → watermark 41 rule as claimed.
  • Cross-referenced the comment pointing at clean_stream_end_returns_stream_ended — that test exists (ingester/tests.rs:205), and Ingester::run does return Err(StreamEnded) at stream end, so unwrap_err() is correct.
  • info.signature = signature(9)… is required (the ingester drops malformed-signature frames); the event asserted carries no signature, so the ingester-parsed sig vs. the fixture sig don't conflict.

One optional coverage note posted inline: the harness now records Watermark and DeadLetter calls too, but no test asserts those run() paths yet — a follow-up case would pin the empty-transaction watermark write and the dead-letter write for free. Not blocking.
· solana-indexer/PR9-pipeline-test

Comment on lines +604 to +615
assert_eq!(
persistence.calls(),
vec![Call::PersistEvents {
events: vec![DecodedEvent::Settlement(SettlementEvent::OrderCreated {
order_uid: expected_uid,
owner: Pubkey::new_from_array([0x11; 32]),
created_by,
})],
watermark: Slot(41),
}]
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional (coverage): this new harness records three Call variants, but only PersistEvents is ever asserted. The Watermark path (events.is_empty()write_watermark) and the DeadLetter path (decode_failedwrite_dead_letter) in Decoder::run are still unobserved end-to-end — decode_wraps_events_and_skips_reverted_transactions exercises the reverted/empty case at the decode() level but not through run(), so the slot - 1 watermark write for an empty transaction and the dead-letter write are never pinned.

Since the seam now makes both observable for free, consider a second pipeline case (e.g. a reverted tx → Call::Watermark(Slot(41)), and an unknown-discriminator tx → a trailing Call::DeadLetter { .. }). Not blocking for this PR's stated scope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant